/*+*********************************************************
Filename: A01_mic_dac_uart\src\top.v
Description:
  transfer mic data to uart and dac.

Modification:
2024.02.28 creation, mic to uart by H.Zheng  (02_mic_uart01)
2024.02.29 add mic to dac.  (02_mic_dac01)
2024.04.15 add comment and python script and upload to gitee. (A01_mic_dac_uart)
**********************************************************-*/
module top(
	input wire clk,
	input wire rst_n,
	input wire uart_rx,
	output wire uart_tx,
  output wire [5:0] led, 

  output wire mic_ws,
  output wire mic_ck,
  output wire mic_lr,
  input wire mic_data,

  output wire dac_ws,
  output wire dac_bck,
  output wire dac_data,
  output wire dac_pa_en

);


/**
 * clock section
 */
  wire clk1m;
  wire clk6m;
  PLL_6M PLL6m(
      .clkout(clk6m),
      .clkoutd(clk1m),
      .clkin(clk)
  );



/**
 * uart section
 */

  parameter                        CLK_FRE  = 27;//Mhz  
  //Baud rate set to 500kHz
  parameter                        UART_FRE = 500000;//hz
  wire[7:0]                         tx_data;
  wire                              tx_data_valid;
  wire                             tx_data_ready;

  uart_tx#(	.CLK_FRE(CLK_FRE),	.BAUD_RATE(UART_FRE)) uart_tx_inst(
    .clk                        (clk                      ),
    .rst_n                      (rst_n                    ),
    .tx_data                    (tx_data                  ),
    .tx_data_valid              (tx_data_valid            ),
    .tx_data_ready              (tx_data_ready            ),
    .tx_pin                     (uart_tx                  )
  );

/**
 * mic section
 * digital mic: MSM261S4030H0
 */
  assign mic_lr = 1'b0;

  reg [7:0] mic_counter;

  always @(posedge clk6m or negedge rst_n) begin
      if (!rst_n)
          mic_counter <= 8'd0;
      else
          mic_counter <= mic_counter + 1'd1;
  end

  wire clk_3072kHz_n = mic_counter[0];  //6/2
  wire clk_48kHz_n   = mic_counter[6]; //3/64=6/128

  assign mic_ck = clk_3072kHz_n;
  assign mic_ws = clk_48kHz_n;


  //
  // receive mic data
  //
  reg [63:0] shift_reg;

  always @(posedge mic_ck) begin
      shift_reg <= {shift_reg[62:0], mic_data};	
  end	
    
  reg [63:0] data_reg;
  always  @(negedge mic_ws) begin
      data_reg <= shift_reg;
  end		

  wire[23:0] data_l = data_reg[62:39];	
  wire[23:0] data_r = data_reg[30:7];	    

  //it's signed data, calculate amplitude
  wire[22:0] l_amplitude = data_l[23] ? ((~data_l[22:0])+1'b1) : data_l[22:0];
  wire loud_voice = (l_amplitude[22:16]>=7'h07) ? 1'b1 : 1'b0;    


/**
 * mic data to uart
 */
  //uart tx data and trigger signal
  assign tx_data = data_l[23:16];

  //construct a mic_ws posedge pulse
  reg [1:0] mic_ws_edge;
  always @(negedge clk) begin
      mic_ws_edge <= {mic_ws_edge[0], mic_ws};	
  end
  assign tx_data_valid = (~mic_ws_edge[1]) & mic_ws_edge[0]; //posedge of mic_ws trigger a uart tx


/**
 * DAC interface
 */
  assign dac_bck = mic_counter[1]; //32 bck per ws period

  dac_pt8211 pt8211_u1(
    .data_in_clk(tx_data_valid),
    .data_r(data_r[23:8]),
    .data_l(data_l[23:8]),
//      .data_r({data_l[23], data_l[19:5]}), //large voice
//      .data_l({data_l[23], data_l[19:5]}), //large voice
    .dac_if_bck(dac_bck),
    .dac_if_ws(dac_ws),
    .dac_if_data(dac_data)
  );

  assign dac_pa_en = 1'b1;




/**
 * led
 */
assign led = {5'b11111 , ~loud_voice};
//assign led = ~l_amplitude[22:17];

endmodule